﻿Imports System.Text.RegularExpressions

Public Class frmConversion
    Const InchAndMM As Single = 25.4F
    Dim MoveDown As Boolean = False
    Dim MoveY As Integer, TimCount As Integer = 0
    Private Sub frmConversion_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ChangeButtonColor(Btn_Convert)
        With Cbo_ConvertMode
            .Items.Add("毫米转英寸")
            .Items.Add("英寸转毫米")
            .Items.Add("十六进制转十进制")
            .Items.Add("十进制转十六进制")
            .Items.Add("十进制转二进制")
            .Items.Add("二进制转十进制")
            .Items.Add("十进制转VisualBasic十六进制")
            .Items.Add("十进制转C#十六进制")
            .SelectedIndex = 0
            TipText.Top = Me.ClientRectangle.Height
            Panel1.BringToFront()
        End With
    End Sub
#Region "判断是否是数值型数据"
    Public Shared Function IsNumber(ByVal value As String) As Boolean
        If value = "0" OrElse String.IsNullOrEmpty(value) Then
            Return True
        End If
        Dim r As New Regex("^[+-]?[0-9]+[.]?[0-9]+$")
        If value.Length = 1 Then
            Dim g As New Regex("^[0-9]+$")
            Return g.IsMatch(value)
        End If
        Return r.IsMatch(value)
    End Function
    Public Shared Function IsBinaryNumber(ByVal value As String) As Boolean
        If value = "0" OrElse String.IsNullOrEmpty(value) Then
            Return True
        End If
        Dim r As New Regex("^[+-]?[0-1]+[.]?[0-1]+$")
        If value.Length = 1 Then
            Dim g As New Regex("^[0-1]+$")
            Return g.IsMatch(value)
        End If
        Return r.IsMatch(value)
    End Function
    Public Shared Function IsHexNumber(ByVal value As String) As Boolean
        If value = "0" OrElse String.IsNullOrEmpty(value) Then
            Return True
        End If
        Dim r As New Regex("^[0x]?[0-9]+[A]?[B]?[C]?[D]?[E]?[F]+$")
        If value.Length = 1 Then
            Dim g As New Regex("^[0-1]+$")
            Return g.IsMatch(value)
        End If
        Return r.IsMatch(value)
    End Function
#End Region
    Private Sub HexadecimalConversion(ByVal value As String)
        Dim Tmp As String = TB_ConvertValue.Text
        If [String].IsNullOrEmpty(Tmp) Then
            MessageBox.Show(Me, "需转换数值文本不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return
        End If
        Try
            Select Case value
                Case ("毫米转英寸")
                    If True Then
                        If IsNumber(Tmp) = False Then
                            Throw New Exception("转换文本不能含有中文和特殊字符！")
                        End If
                        TB_Result.Text = MMsubInch(Tmp).ToString()
                        Exit Select
                    End If
                Case "英寸转毫米"
                    If True Then
                        If IsNumber(Tmp) = False Then
                            Throw New Exception("转换文本不能含有中文和特殊字符！")
                        End If
                        TB_Result.Text = InchSubMM(Tmp).ToString()
                        Exit Select
                    End If
                Case "二进制转十进制"
                    If True Then
                        If IsBinaryNumber(Tmp) = False Then
                            Throw New Exception("转换文本只能含有[0，1，.！]")
                        End If
                        TB_Result.Text = BinaryToDecimalSub(Tmp).ToString()
                        Exit Select
                    End If
                Case "十进制转二进制"
                    If True Then
                        If IsNumber(Tmp) = False Then
                            Throw New Exception("转换文本不能含有中文和特殊字符！")
                        End If
                        TB_Result.Text = DecToBin(Tmp)
                        Exit Select
                    End If
                Case "十进制转十六进制"
                    If True Then
                        If IsNumber(Tmp) = False Then
                            Throw New Exception("转换文本不能含有中文和特殊字符！")
                        End If
                        TB_Result.Text = DectoHex(Convert.ToInt32(Tmp))
                        Exit Select
                    End If
                Case "十六进制转十进制"
                    '   if (IsHexNumber(Tmp) == false) { throw new Exception("转换文本必须为十六进制数据！"); }
                    TB_Result.Text = HexToDec(Tmp).ToString()
                    Exit Select
                Case "十进制转VisualBasic十六进制"
                    TB_Result.Text = GetDecToVBHex(TB_ConvertValue.Text)
                Case "十进制转C#十六进制"
                    TB_Result.Text = GetDecToCShapHex(TB_ConvertValue.Text)
                Case Else
                    TB_Result.Text = ""
            End Select
            Clipboard.SetText(TB_Result.Text)
            Dim TipHeight As Integer
            TipText.AutoSize = True
            TipText.Text = "转换结果：【" + TB_Result.Text + "】已复制到剪贴板！"
            TipHeight = TipText.Height
            If TipText.Width > Me.ClientRectangle.Width Then
                TipText.AutoSize = False
                TipText.Width = Me.ClientRectangle.Width
                TipText.Height = TipHeight * 2
                TipText.Left = 0
            Else
                TipText.AutoSize = True
                TipText.Left = (Me.ClientRectangle.Width - TipText.Width) / 2
            End If
            MoveY = Me.ClientRectangle.Height
            MoveDown = False
            TimCount = 0
            Timer1.Enabled = True
        Catch ex As Exception
            MessageBox.Show(Me, ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.[Error])
        End Try
    End Sub
    '=============================================转换函数
    Private Function InchSubMM(ByVal value As String) As Double
        '英寸转毫米
        Try
            Return (Convert.ToDouble(value) * 25.4)
        Catch ex As Exception
            MessageBox.Show(Me, ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.[Error])
            Return -1
        End Try
    End Function
    Private Function MMsubInch(ByVal value As String) As Double
        '毫米转英寸
        Try
            Dim result As Double
            result = Convert.ToDouble(value) / 25.4
            Return result
        Catch ex As Exception
            MessageBox.Show(Me, ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.[Error])
            Return -1
        End Try
    End Function
    Private Function RGB2HEX(ByVal R As Byte, ByVal G As Byte, ByVal B As Byte) As String
        'RGB转HEX  1
        Return "#" & Convert.ToString(Color.FromArgb(R, G, B).ToArgb(), 16).Substring(2)
    End Function
    Private Function RGB2HEX(ByVal A As Byte, ByVal R As Byte, ByVal G As Byte, ByVal B As Byte) As String
        'RGB转HEX  2
        Return "#" & Convert.ToString(Color.FromArgb(A, R, G, B).ToArgb(), 16).Substring(2)
    End Function
    Private Function BinaryToDecimalSub(ByVal value As String) As Double
        '二进制转十进制
        Dim a As Integer = -1
        Dim str1 As String, str2 As String
        Dim Sum1 As Double = 0, Sum2 As Double = 0
        a = value.IndexOf(".")
        If a > 0 Then
            str1 = value.Substring(0, a)
            str2 = value.Substring(a + 1)
            For i = str1.Length - 1 To 0 Step -1
                Sum1 += Convert.ToInt32(str1.Substring(i, 1)) * Math.Pow(2, Math.Abs((i - value.Length + 1)))
            Next
            For j As Integer = 0 To str2.Length - 1
                Sum2 += Convert.ToInt32(str2.Substring(j, 1)) * Math.Pow(2, (-(j + 1)))
            Next
            Return Sum1 + Sum2
        Else
            For i = value.Length - 1 To 0 Step -1
                Sum1 += 1 * Math.Pow(2, Math.Abs((i - value.Length + 1)))
            Next
            Return Sum1
        End If
        '  return null;
    End Function

    Private Function DecToBin(ByVal value As String) As String
        '十进制转二进制
        Dim a As Integer
        Dim str1 As String, str2 As String
        Dim Result As String = "", Tmp1 As String = "", Tmp4 As String = ""
        Dim TmpValue1 As Integer, TmpValue2 As Integer
        Dim Tmp2 As Double, Tmp3 As Double
        a = value.IndexOf(".")
        If a > 0 Then
            str1 = value.Substring(0, a)
            str2 = value.Substring(a + 1)
            TmpValue1 = Convert.ToInt32(str1)
            While TmpValue1 >= 1
                TmpValue2 = TmpValue1 Mod 2
                TmpValue1 = TmpValue1 \ 2
                Tmp1 += TmpValue2.ToString()
            End While
            For i As Integer = Tmp1.Length - 1 To 0 Step -1
                Result += Tmp1.Substring(i, 1)
            Next
            Result += "."
            Tmp2 = Convert.ToDouble("0." & str2)
            Tmp3 = Convert.ToInt32(str2)
            While Tmp3 <> 0
                Tmp2 = Tmp2 * 2
                str2 = Tmp2.ToString()
                a = str2.IndexOf(".")
                If a > 0 Then
                    str1 = str2.Substring(0, a)
                    Tmp4 = str2.Substring(a + 1)
                    Tmp2 = Convert.ToDouble("0." & Tmp4)
                    Tmp3 = Convert.ToInt32(Tmp4)
                    Result += str1
                Else
                    Result += "1"
                    Tmp3 = 0
                End If
            End While
            Return Result
        Else
            TmpValue1 = Convert.ToInt32(value)
            While TmpValue1 >= 1
                TmpValue2 = TmpValue1 Mod 2
                TmpValue1 = TmpValue1 \ 2
                Tmp1 += TmpValue2.ToString()
            End While
            For i As Integer = Tmp1.Length - 1 To 0 Step -1
                Result += Tmp1.Substring(i, 1)
            Next
            Return Result
        End If
    End Function
    '========================================十六进制转换十进制
    Private Function HexToDec(ByVal value As String) As Integer
        Dim HexData As String = "0123456789ABCDEF"
        Dim TmpValue As Integer = 0, sIndex As Integer
        Dim Tmp As String
        For i As Integer = value.Length - 1 To 0 Step -1
            Tmp = value.Substring(i, 1).ToUpper()
            sIndex = HexData.IndexOf(Tmp)
            TmpValue += Convert.ToInt32(sIndex * Math.Pow(16, value.Length - 1 - i))
        Next
        Return TmpValue
    End Function
    Private Function DectoHex(ByVal value As Integer) As String
        Dim x As String = ""
        If value < 16 Then
            x = GetHexString(value)
        Else
            Dim c As Integer
            Dim n As Integer = value, temp As Integer = value
            Dim tmp As String = "", s As String = ""
            While n > 0
                c = n Mod 16
                n = n \ 16
                tmp += GetHexString(c)
            End While
            For i As Integer = tmp.Length - 1 To 0 Step -1
                s += tmp.Substring(i, 1)
            Next
            x = s
        End If
        Return x
    End Function
    Private Function GetHexString(ByVal value As Integer) As String
        Select Case value
            Case 10
                Return "A"
            Case 11
                Return "B"
            Case 12
                Return "C"
            Case 13
                Return "D"
            Case 14
                Return "E"
            Case 15
                Return "F"
            Case Else
                Return value.ToString()
        End Select
    End Function
    Private Function GetDecToVBHex(ByVal value As String) As String
        If IsNumber(value) = False Then MsgBox("转换数值必须是数值型数据！", MsgBoxStyle.Information, "提示")
        Return "&H" + DectoHex(Convert.ToInt32(value))
    End Function
    Private Function GetDecToCShapHex(ByVal value As String) As String
        If IsNumber(value) = False Then MsgBox("转换数值必须是数值型数据！", MsgBoxStyle.Information, "提示")
        Return "0x" + DectoHex(Convert.ToInt32(value))
    End Function
    '=============================================转换函数

    Private Sub Btn_Convert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn_Convert.Click
        HexadecimalConversion(Cbo_ConvertMode.Text)
    End Sub

    Private Sub TB_Result_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TB_Result.KeyPress
        e.Handled = True
    End Sub

    Private Sub TB_ConvertValue_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TB_ConvertValue.KeyPress
        If Asc(e.KeyChar) = 13 Then
            Call HexadecimalConversion(Cbo_ConvertMode.Text)
        End If
    End Sub

    Private Sub TipText_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TipText.Click

    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If MoveDown = False Then
            MoveY -= 1
            TipText.Top = MoveY
            If TipText.Top <= Me.ClientRectangle.Height - TipText.Height Then Timer2.Enabled = True : Timer1.Enabled = False
        Else
            MoveY += 1
            TipText.Top = MoveY
            If TipText.Top >= Me.ClientRectangle.Height Then
                Timer1.Enabled = False
            End If
        End If
    End Sub

    Private Sub Timer2_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        TimCount = TimCount + 1
        If TimCount > 5 Then
            MoveDown = True
            Timer1.Enabled = True
            Timer2.Enabled = False
        End If
    End Sub
End Class